﻿Imports SdlDotNet.Graphics
Imports SdlDotNet.Graphics.Sprites
Imports System.Drawing
Imports System.Timers

Public Class Bomber
    Implements ITemporaryDrawableEntity

    Private CommandCenterLocation As Point
    Private ReadOnly BomberFlyingUp As New Surface("resources\images\game\Bomber.png")
    Private ReadOnly BomberFlyingLeft As Surface = BomberFlyingUp.CreateRotatedSurface(90)
    Private ReadOnly BomberFlyingRight As Surface = BomberFlyingUp.CreateRotatedSurface(-90)
    Private ReadOnly BomberFlyingDown As Surface = BomberFlyingUp.CreateRotatedSurface(180)

    Private _currentOrientation As Orientation = Orientation.Left

    Private Property CurrentOrientation() As Orientation
        Get
            Return _currentOrientation
        End Get
        Set(ByVal value As Orientation)
            If (value <> _currentOrientation) Then
                _currentOrientation = value
                If (value = Orientation.Down) Then
                    BomberSprite.Surface = BomberFlyingDown
                ElseIf (value = Orientation.Left) Then
                    BomberSprite.Surface = BomberFlyingLeft
                ElseIf (value = Orientation.Right) Then
                    BomberSprite.Surface = BomberFlyingRight
                ElseIf (value = Orientation.Up) Then
                    BomberSprite.Surface = BomberFlyingUp
                End If
            End If
        End Set
    End Property

    Private BomberSprite As New Sprite(BomberFlyingLeft)

    Private WithEvents timer As New Timer(1)

    Private DestinationList As New List(Of Point)
    Private CurrentDestinationIndex As Integer = 0

    Private CurrentPosition As Point
    Private CurrentStatus As BomberStatus = BomberStatus.AwaitingOrders

    Private CurrentTargetPlayer As Player
    Private CurrentTargetCity As City
    Private CurrentAmountOfDamageToDo As Integer

    Public Event NoLongerInUse(ByRef sender As ITemporaryDrawableEntity) Implements ITemporaryDrawableEntity.NoLongerInUse
    Public Event NuclearExplosion(ByVal position As Point)
    Public Event Explosion(ByVal position As Point)
    Public Event BomberDestroyedByAntiAircraft(ByRef defendingPlayer As Player, ByRef bomberOwner As Player)
    Private Owner As Player

    Public Sub New(ByVal commandCenterLocation As Point, ByRef owner As Player)
        Me.Owner = owner
        Me.CommandCenterLocation = commandCenterLocation
        CurrentPosition = commandCenterLocation
        CircleBase()
        timer.Start()
    End Sub

    Public Sub CircleBase()
        CurrentStatus = BomberStatus.AwaitingOrders
        DestinationList.Clear()
        CurrentDestinationIndex = 0
        DestinationList.Add(New Point(CommandCenterLocation.X - 50, CommandCenterLocation.Y - 50))
        DestinationList.Add(New Point(CommandCenterLocation.X + 50, CommandCenterLocation.Y - 50))
        DestinationList.Add(New Point(CommandCenterLocation.X + 50, CommandCenterLocation.Y + 50))
        DestinationList.Add(New Point(CommandCenterLocation.X - 50, CommandCenterLocation.Y + 50))
    End Sub

    Public Sub BombTarget(ByVal targetPlayer As Player, ByVal targetCity As City, ByVal amountOfDamageToDo As Integer)
        Me.CurrentTargetCity = targetCity
        Me.CurrentTargetPlayer = targetPlayer
        Me.CurrentAmountOfDamageToDo = amountOfDamageToDo
        DestinationList.Clear()
        CurrentDestinationIndex = 0
        DestinationList.Add(targetCity.Position)
        CurrentStatus = BomberStatus.Bombing
    End Sub

    Public Sub Dispose() Implements ITemporaryDrawableEntity.Dispose
        BomberSprite.Dispose()
        timer.Dispose()
    End Sub

    Public Sub Draw(ByRef display As SdlDotNet.Graphics.Surface) Implements ITemporaryDrawableEntity.Draw
        display.Blit(BomberSprite, currentPosition)
    End Sub

    Private Sub PerformBombing()
        CurrentStatus = BomberStatus.AwaitingOrders

        If (CurrentTargetPlayer.AntiAircraftDeployed) Then
            RaiseEvent Explosion(CurrentPosition)
            RaiseEvent BomberDestroyedByAntiAircraft(CurrentTargetPlayer, Owner)
        Else
            CurrentTargetCity.Health -= CurrentAmountOfDamageToDo
            RaiseEvent NuclearExplosion(CurrentTargetCity.Position)
            CircleBase()
        End If
    End Sub

    Private Sub timer_Elapsed(ByVal sender As Object, ByVal e As System.Timers.ElapsedEventArgs) Handles timer.Elapsed
        If (HasReachedDestination()) Then
            If (CurrentStatus = BomberStatus.Bombing) Then
                PerformBombing()
            Else
                MoveToNextDestination()
            End If
        End If

        Dim newPosition As Point = New Point(CurrentPosition.X, CurrentPosition.Y)

        If (CurrentPosition.X > DestinationList(CurrentDestinationIndex).X) Then
            CurrentOrientation = Orientation.Left
            newPosition.X -= 1
        ElseIf (CurrentPosition.X < DestinationList(CurrentDestinationIndex).X) Then
            CurrentOrientation = Orientation.Right
            newPosition.X += 1
        ElseIf (CurrentPosition.Y > DestinationList(CurrentDestinationIndex).Y) Then
            CurrentOrientation = Orientation.Up
            newPosition.Y -= 1
        ElseIf (CurrentPosition.Y < DestinationList(CurrentDestinationIndex).Y) Then
            CurrentOrientation = Orientation.Down
            newPosition.Y += 1
        End If

        CurrentPosition = newPosition
    End Sub

    Private Function HasReachedDestination() As Boolean
        Try
            If (CurrentPosition = DestinationList(CurrentDestinationIndex)) Then
                Return True
            Else
                Return False
            End If
        Catch ex As Exception
            Return True 'this is stupid and shouldn't be done this way. Problem is, sometimes currentDestinationIndex is out of range
        End Try
    End Function

    Private Sub MoveToNextDestination()
        currentDestinationIndex += 1
        If (destinationList.Count <= currentDestinationIndex) Then
            currentDestinationIndex = 0
        End If
    End Sub
End Class
